#include "BrushGUI.hpp"
#include <Graphics\ColorDefine.hpp>
#include <zImage.hpp>

namespace zzz {
BrushGUI::BrushGUI()
:sel_id_(1), brushsize_(5),
left_(false), right_(false)
{

}

void BrushGUI::Prepare(const Image4f &img)
{
  ori_=img;
  mask_.SetSize(ori_.Size());
  mask_.Zero();
  show_=ori_;
}

bool BrushGUI::OnMouseMove(unsigned int nFlags,int x,int y)
{
  x_ = x;
  y_ = y;
  if (ori_.size()==0) return false;
  pos_ = Vector2ui(renderer_->GetHoverPixel(x,y));

  if (left_) {
    ImageDrawer<zuchar> drawer(mask_);
    vector<Vector2i> path;
    RasterizeLine(last_[0], last_[1], pos_[0], pos_[1], path);
    for (zuint i=0; i<path.size(); i++)
      drawer.FillCircle(sel_id_, path[i][0], path[i][1], brushsize_);
    last_=pos_;
  } else if (right_) {
    ImageDrawer<zuchar> drawer(mask_);
    vector<Vector2i> path;
    RasterizeLine(last_[0], last_[1], pos_[0], pos_[1], path);
    for (zuint i=0; i<path.size(); i++)
      drawer.FillCircle(0, path[i][0], path[i][1], brushsize_);
    last_=pos_;
  }
  PrepareShow();
  renderer_->Redraw();
  return true;
}

bool BrushGUI::OnLButtonDown(unsigned int nFlags,int x,int y)
{
  left_=true;
  if (!show_.IsInside(pos_)) return false;
  last_ = pos_;
  OnMouseMove(nFlags, x, y);
  return true;
}

bool BrushGUI::OnLButtonUp(unsigned int nFlags,int x,int y)
{
  left_=false;
  return true;
}

bool BrushGUI::OnRButtonDown(unsigned int nFlags,int x,int y)
{
  right_ = true;
  if (!show_.IsInside(pos_)) return false;
  last_ = pos_;
  OnMouseMove(nFlags, x, y);
  return true;
}

bool BrushGUI::OnRButtonUp(unsigned int nFlags,int x,int y)
{
  right_ = false;
  return true;
}

bool BrushGUI::OnKeyDown(unsigned int nChar, unsigned int nRepCnt, unsigned int nFlags)
{
  if (nChar == ZZZKEY_MINUS) {
    if (brushsize_ > 0) 
      brushsize_--;
  } else if (nChar == ZZZKEY_EQUAL) {
    brushsize_++;
  }
  return true;
}

void BrushGUI::PrepareShow()
{
  for (zuint i=0; i<show_.size(); i++)
    if (mask_[i]!=0)
      show_[i]=ori_.at(i) * *(ColorDefine::DistinctValue[mask_[i]]);
    else
      show_[i]=ori_.at(i);

  //draw mouse position
  ImageDrawer<Vector4f> drawer(show_);
  drawer.DrawCircle(Vector4f(0.8,0.8,0.8,1),pos_[0],pos_[1],brushsize_);
}

};  // namespace zzz